<template>
  <div class="app-container">
    <!-- 顶部操作按钮 -->
    <el-row class="mb-3">
      <el-col :span="24" class="text-right">
        <el-button type="danger" :icon="Delete" plain @click="batchDelete" :disabled="!hasSelected">批量删除</el-button>
        <el-button type="success" @click="addPage" :icon="Plus">新增菜单</el-button>
        <el-button type="primary" @click="resetQueryForm" :icon="RefreshRight">刷新</el-button>
      </el-col>
    </el-row>

    <!-- 菜单列表表格 -->
    <el-row>
      <el-col :span="24">
        <el-table
            :data="list"
            border
            stripe
            row-key="id"
            @selection-change="handleParentSelectionChange"
            v-loading="menuLoading"
            element-loading-text="加载菜单中..."
        >
          <el-table-column type="selection" width="55" />
          <el-table-column type="expand">
            <template #default="props">
              <div class="submenu-container">
                <el-table
                    :data="props.row.childList"
                    border
                    @selection-change="(selection) => handleChildSelectionChange(selection, props.row)"
                >
                  <el-table-column type="selection" width="55" />
                  <el-table-column prop="id" label="ID" width="80" />
                  <el-table-column prop="permissionName" label="菜单名称" width="180" />
                  <el-table-column prop="sort" label="排序" width="80" />
                  <el-table-column label="图标" width="100">
                    <template #default="scope">
                      <el-icon v-if="scope.row.icon" style="font-size: 18px;">
                        <component :is="scope.row.icon" />
                      </el-icon>
                    </template>
                  </el-table-column>
                  <el-table-column prop="permissionUrl" label="网址" min-width="200" />
                  <el-table-column label="状态" width="120">
                    <template #default="scope">
                      <el-switch
                          :model-value="String(scope.row.status ?? 1)"
                          inline-prompt
                          active-value="1"
                          active-text="正常"
                          inactive-value="0"
                          inactive-text="停用"
                          class="ml-2"
                          style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
                          @change="switchHandler(scope.row)"
                      />
                    </template>
                  </el-table-column>
                  <el-table-column label="操作" width="160">
                    <template #default="scope">
                      <el-button type="primary" size="small" @click="edit(scope.row)">修改</el-button>
                      <el-button type="danger" size="small" @click="deleteOne(scope.row)" style="margin-left: 5px;">删除</el-button>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="id" label="ID" width="80" />
          <el-table-column prop="permissionName" label="菜单名称" width="180" />
          <el-table-column prop="sort" label="排序" width="80" />
          <el-table-column label="图标" width="100">
            <template #default="scope">
              <el-icon v-if="scope.row.icon" style="font-size: 18px;">
                <component :is="scope.row.icon" />
              </el-icon>
            </template>
          </el-table-column>
          <el-table-column prop="permissionUrl" label="网址" min-width="200" />
          <el-table-column label="状态" width="120">
            <template #default="scope">
              <el-switch
                  :model-value="String(scope.row.status ?? 1)"
                  inline-prompt
                  active-value="1"
                  active-text="正常"
                  inactive-value="0"
                  inactive-text="停用"
                  class="ml-2"
                  style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
                  @change="switchHandler(scope.row)"
              />
            </template>
          </el-table-column>
          <el-table-column label="操作" width="160">
            <template #default="scope">
              <el-button type="primary" size="small" @click="edit(scope.row)">修改</el-button>
              <el-button type="danger" size="small" @click="deleteOne(scope.row)" style="margin-left: 5px;">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-col>
    </el-row>

    <!-- 分页控件 -->
    <el-row class="mt-3">
      <el-col :span="24" class="text-right">
        <el-pagination
            v-model:current-page="queryParams.pageNum"
            v-model:page-size="queryParams.pageSize"
            :page-sizes="[5, 10, 20, 50]"
            :background="true"
            layout="total, sizes, prev, pager, next, jumper"
            :total="queryParams.total"
            @size-change="query"
            @current-change="query"
        />
      </el-col>
    </el-row>
  </div>

  <!-- 新增/编辑菜单弹窗 -->
  <el-dialog v-model="editFormVisible" :title="editTitle" width="600px" append-to-body>
    <el-form
        :model="editForm"
        :rules="editFormRules"
        ref="editFormRef"
        label-width="100px"
        class="mt-2"
    >
      <el-row>
        <el-col :span="24">
          <el-form-item label="父级菜单" prop="parentId">
            <el-tree-select
                v-model="editForm.parentId"
                :data="optionList"
                :props="{
                value: 'id',
                label: 'permissionName',
                children: 'childList'
              }"
                value-key="id"
                placeholder="选择父级菜单"
                check-strictly
                style="width: 100%;"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-form-item label="菜单图标" prop="icon">
            <el-popover
                placement="bottom-start"
                :width="540"
                trigger="click"
            >
              <template #reference>
                <el-input
                    v-model="editForm.icon"
                    placeholder="点击选择图标"
                    @focus="showSelectIcon"
                    readonly
                >
                  <template #prefix>
                    <el-icon v-if="editForm.icon" style="height: 32px; width: 16px;">
                      <component :is="editForm.icon" />
                    </el-icon>
                    <SearchIcon v-else style="height: 32px; width: 16px;" />
                  </template>
                </el-input>
              </template>
              <icon-select ref="iconSelectRef" @selected="selected" :active-icon="editForm.icon" />
            </el-popover>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="菜单名称" prop="permissionName">
            <el-input
                v-model="editForm.permissionName"
                placeholder="请输入菜单名称"
                maxlength="30"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="菜单网址" prop="permissionUrl">
            <el-input
                v-model="editForm.permissionUrl"
                placeholder="请输入网址（如/system/menu）"
                maxlength="100"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="显示排序" prop="sort">
            <el-input-number
                v-model="editForm.sort"
                controls-position="right"
                :min="0"
                style="width: 100%;"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="状态" prop="status">
            <el-radio-group v-model="editForm.status">
              <el-radio-button label="1">正常</el-radio-button>
              <el-radio-button label="0">停用</el-radio-button>
            </el-radio-group>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="save">确定</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import {
  Delete,
  Edit,
  RefreshRight,
  Plus,
  Search as SearchIcon
} from '@element-plus/icons-vue'
import { ref, onMounted, computed } from "vue";
import api from '@/utils/request.js';
import { ElMessage, ElMessageBox } from "element-plus";
import IconSelect from "@/components/IconSelect/index.vue";

let queryParams = ref({
  pageNum: 1,
  pageSize: 10,
  name: '',
  total: 0
})
let list = ref([])
let optionList = ref([])
let menuLoading = ref(false)

// 选中状态管理
const selectedParentRows = ref([]);
const selectedChildRows = ref({}); // 使用对象存储，key为父菜单ID
const hasSelected = computed(() => {
  return selectedParentRows.value.length > 0 ||
      Object.values(selectedChildRows.value).some(arr => arr.length > 0);
});

let editFormVisible = ref(false)
let editForm = ref({
  id: '',
  permissionName: '',
  permissionUrl: '',
  parentId: '-1',
  icon: '',
  sort: 0,
  status: "1"
})
let editTitle = ref('编辑')
const editFormRef = ref(null)

const editFormRules = {
  permissionName: [
    { required: true, message: '请输入菜单名称', trigger: 'blur' },
    { min: 2, max: 30, message: '菜单名称长度在2-30个字符之间', trigger: 'blur' }
  ],
  permissionUrl: [
    { required: true, message: '请输入菜单网址', trigger: 'blur' },
    { pattern: /^\/[\w\/]*$/, message: '网址必须以/开头，仅含字母、数字、下划线和/', trigger: 'blur' }
  ],
  parentId: [
    { required: true, message: '请选择父级菜单', trigger: 'change' }
  ],
  icon: [
    { required: true, message: '请选择菜单图标', trigger: 'change' }
  ],
  sort: [
    { required: true, message: '请输入排序号', trigger: 'blur' },
    { type: 'number', message: '排序号必须为非负整数', trigger: 'blur' }
  ]
}

// 处理一级菜单选择变化
const handleParentSelectionChange = (val) => {
  selectedParentRows.value = val;
};

// 处理子菜单选择变化
const handleChildSelectionChange = (val, parentRow) => {
  selectedChildRows.value[parentRow.id] = val;
};

let resetQueryForm = () => {
  queryParams.value = {
    pageNum: 1,
    pageSize: 10,
    name: '',
    total: 0
  }
  query();
}

let query = () => {
  menuLoading.value = true;
  api.get("/permission/page", queryParams.value).then(result => {
    if (result.code === 200) {
      list.value = (result.data.list || []).map(menu => ({
        ...menu,
        status: menu.status ?? 1
      }));
      queryParams.value.total = result.total || (result.data?.total) || 0;
      generateOptionList();
    } else {
      ElMessage.error(result.msg || '获取菜单列表失败');
      list.value = [];
    }
  }).catch(err => {
    ElMessage.error('获取菜单列表失败');
    console.error('接口请求错误：', err);
    list.value = [];
  }).finally(() => {
    menuLoading.value = false;
  })
}

const generateOptionList = () => {
  const oneLevelMenus = list.value.map(menu => ({
    id: menu.id,
    permissionName: menu.permissionName,
    childList: []
  }));
  optionList.value = [{
    id: '-1',
    permissionName: '无（一级菜单）',
    childList: oneLevelMenus
  }];
}

let addPage = () => {
  editFormVisible.value = true;
  editTitle.value = "新增菜单";
  resetForm();
  editForm.value.sort = findMaxSort(list.value) + 1;
}

function findMaxSort(menuList) {
  let max = 0;
  menuList.forEach(menu => {
    if (menu.sort > max) max = menu.sort;
    if (menu.childList && menu.childList.length > 0) {
      const childMax = findMaxSort(menu.childList);
      max = Math.max(max, childMax);
    }
  });
  return max;
}

let edit = (row) => {
  editFormVisible.value = true;
  editTitle.value = `编辑菜单：${row.permissionName}`;
  editForm.value = {
    id: row.id,
    permissionName: row.permissionName,
    permissionUrl: row.permissionUrl,
    parentId: String(row.parentId ?? -1),
    icon: row.icon || '',
    sort: row.sort || 0,
    status: String(row.status ?? 1)
  };
}

function resetForm() {
  editForm.value = {
    id: '',
    permissionName: '',
    permissionUrl: '',
    parentId: '-1',
    icon: '',
    sort: 0,
    status: "1"
  };
  if (iconSelectRef.value) iconSelectRef.value.reset();
  if (editFormRef.value) editFormRef.value.clearValidate();
}

function cancel() {
  editFormVisible.value = false;
  resetForm();
}

function save() {
  editFormRef.value.validate((isValid) => {
    if (!isValid) return;
    const submitData = {
      id: editForm.value.id,
      permissionName: editForm.value.permissionName,
      permissionUrl: editForm.value.permissionUrl,
      parentId: Number(editForm.value.parentId),
      icon: editForm.value.icon,
      sort: editForm.value.sort,
      status: Number(editForm.value.status)
    };
    const apiMethod = editForm.value.id ? api.putJson : api.postJson;
    const apiUrl = editForm.value.id ? "/permission/update" : "/permission/add";

    apiMethod(apiUrl, submitData).then(result => {
      if (result.code === 200) {
        ElMessage.success(editForm.value.id ? "编辑菜单成功" : "新增菜单成功");
        editFormVisible.value = false;
        query();
      } else {
        ElMessage.error(result.msg || (editForm.value.id ? "编辑失败" : "新增失败"));
      }
    }).catch(err => {
      ElMessage.error(editForm.value.id ? "编辑菜单失败" : "新增菜单失败");
      console.error('保存接口错误：', err);
    });
  });
}

// 批量删除
const batchDelete = () => {
  // 收集所有选中的ID
  const allSelectedIds = [
    ...selectedParentRows.value.map(row => row.id),
    ...Object.values(selectedChildRows.value).flatMap(arr => arr.map(row => row.id))
  ];

  if (allSelectedIds.length === 0) {
    ElMessage.warning("请选择要删除的菜单");
    return;
  }

  deleteMenus(allSelectedIds);
};

// 单个删除
let deleteOne = (row) => {
  deleteMenus([row.id]);
};

// 统一删除方法
function deleteMenus(ids) {
  const idsStr = ids.join(',');
  ElMessageBox.confirm(`是否确认删除菜单[${idsStr}]？`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    api.delete(`/permission/del?ids=${idsStr}`).then(result => {
      if (result.code === 200) {
        ElMessage.success("删除成功");
        // 清空选中状态
        selectedParentRows.value = [];
        selectedChildRows.value = {};
        query();
      } else {
        ElMessage.error(result.msg || "删除失败");
      }
    }).catch(err => {
      ElMessage.error("删除失败");
      console.error('删除接口错误：', err);
    })
  }).catch(() => {
    ElMessage.info('已取消删除');
  })
}

function switchHandler(row) {
  const originalStatus = row.status;
  const newStatus = originalStatus === 1 ? 0 : 1;

  ElMessageBox.confirm(`是否修改菜单[${row.permissionName}]的状态？`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    api.postJson("/permission/updateStatus", {
      id: row.id,
      status: newStatus
    }).then(res => {
      if (res.code === 200) {
        ElMessage.success("状态修改成功");
        row.status = newStatus;
      } else {
        ElMessage.error(res.msg || "状态修改失败");
        row.status = originalStatus;
      }
    }).catch(() => {
      ElMessage.error("状态修改失败");
      row.status = originalStatus;
    })
  }).catch(() => {
    ElMessage.info('已取消修改');
    row.status = originalStatus;
  })
}

const iconSelectRef = ref(null);
function showSelectIcon() {
  if (iconSelectRef.value) iconSelectRef.value.reset();
}
function selected(iconName) {
  editForm.value.icon = iconName;
}

onMounted(() => {
  resetQueryForm();
  query();
})
</script>

<style scoped>
.mb-3 { margin-bottom: 12px; }
.mt-3 { margin-top: 12px; }
.text-right { text-align: right; }

.submenu-container {
  max-height: 200px;
  overflow-y: auto;
  padding: 10px;
  background-color: #fff;
}
</style>